package com.zuqiuzhandui.liveing.view.streaming;

import android.graphics.Bitmap;
import android.hardware.Camera;
import android.os.Handler;
import android.os.Message;
import android.support.design.widget.BottomSheetDialog;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.code19.library.L;
import com.jakewharton.rxbinding.view.RxView;
import com.jakewharton.rxbinding.view.ViewClickEvent;
import com.qiniu.android.dns.DnsManager;
import com.qiniu.android.dns.IResolver;
import com.qiniu.android.dns.NetworkInfo;
import com.qiniu.android.dns.http.DnspodFree;
import com.qiniu.android.dns.local.AndroidDnsServer;
import com.qiniu.android.dns.local.Resolver;
import com.qiniu.pili.droid.streaming.AVCodecType;
import com.qiniu.pili.droid.streaming.CameraStreamingSetting;
import com.qiniu.pili.droid.streaming.MediaStreamingManager;
import com.qiniu.pili.droid.streaming.MicrophoneStreamingSetting;
import com.qiniu.pili.droid.streaming.StreamingProfile;
import com.qiniu.pili.droid.streaming.StreamingState;
import com.qiniu.pili.droid.streaming.StreamingStateChangedListener;
import com.qiniu.pili.droid.streaming.WatermarkSetting;
import com.qiniu.pili.droid.streaming.widget.AspectFrameLayout;
import com.tencent.mm.sdk.modelmsg.SendMessageToWX;
import com.tencent.mm.sdk.modelmsg.WXMediaMessage;
import com.tencent.mm.sdk.modelmsg.WXWebpageObject;
import com.tencent.mm.sdk.openapi.IWXAPI;
import com.tencent.mm.sdk.openapi.WXAPIFactory;
import com.zuqiuzhandui.R;
import com.zuqiuzhandui.liveing.base.BaseActivity;
import com.zuqiuzhandui.liveing.model.resultModel.LiveCreateRs;
import com.zuqiuzhandui.liveing.model.resultModel.LiveNumberQtyRs;
import com.zuqiuzhandui.liveing.util.ImageUrlUtil;
import com.zuqiuzhandui.liveing.weight.CameraPreviewFrameView;
import com.zuqiuzhandui.liveing.weight.CountDownView;
import com.zuqiuzhandui.liveing.weight.FocusIndicatorRotateLayout;
import com.zuqiuzhandui.testing.myhelper.net.GlideCircleTransform;
import com.zuqiuzhandui.testing.myhelper.util.ToastUtils;

import java.io.IOException;
import java.net.InetAddress;
import java.net.URISyntaxException;
import java.util.concurrent.TimeUnit;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;
import rx.functions.Action1;

import static com.zuqiuzhandui.liveing.util.Util.bmpToByteArray;
import static com.zuqiuzhandui.testing.myhelper.util.ImageUtils.GetLocalOrNetBitmap;

/**
 * Created by yq on 2016-10-09.
 */

public class StreamingActivity extends BaseActivity
        implements StreamingStateChangedListener
        , StreamContract.View
        , CameraPreviewFrameView.Listener {
    @BindView(R.id.cameraPreview_surfaceView)
    CameraPreviewFrameView cameraPreviewSurfaceView;
    @BindView(R.id.cameraPreview_afl)
    AspectFrameLayout afl;
    @BindView(R.id.tv_team_name)
    TextView tvTeamName;
    @BindView(R.id.tv_viewer_count)
    TextView tvViewerCount;
    @BindView(R.id.iv_flashlight)
    ImageView ivFlashlight;
    @BindView(R.id.iv_camera)
    ImageView ivCamera;
    @BindView(R.id.tv_inform)
    TextView tvInform;
    @BindView(R.id.tv_end_live)
    TextView tvEndLive;
    @BindView(R.id.share)
    TextView share;
    @BindView(R.id.activity_swcamera_streaming)
    RelativeLayout activitySwcameraStreaming;
    @BindView(R.id.cdv_main)
    CountDownView countDownView;
    @BindView(R.id.iv_logo)
    ImageView ivLogo;
    @BindView(R.id.focus_indicator_rotate_layout)
    FocusIndicatorRotateLayout mRotateLayout;

    protected static final int MSG_START_STREAMING = 0;
    protected static final int MSG_STOP_STREAMING = 1;
    private static final int MSG_SET_ZOOM = 2;
    private static final int MSG_MUTE = 3;
    private static final int MSG_FB = 4;


    private int mCurrentZoom = 0;
    private int mMaxZoom = 0;
    private String TAG = "StreamingActivity";
    private StreamingProfile mProfile;
    protected MediaStreamingManager mMediaStreamingManager;
    private int mCurrentCamFacingIndex;
    Switcher mSwitcher = new Switcher();
    private StreamContract.Presenter mPresenter;
    private boolean flashlightState = false;
    private LiveCreateRs mLiveData;
    private static final int ZOOM_MINIMUM_WAIT_MILLIS = 33; //ms


    @Override
    public void setViewId() {
        setContentView(R.layout.activity_swcamera_streaming);
    }

    @Override
    public void getBundle() {
        mLiveData = getIntent().getBundleExtra(BUNDLE_KEY).getParcelable(PARCELABLE_KEY);
        setStream(mLiveData.getPublishUrl());
        setViewForBundle();
    }

    private void setViewForBundle() {
        Glide.with(this)
                .load(ImageUrlUtil.processUrl(18, 18, mLiveData.getTeamLogo()))
                .transform(new GlideCircleTransform(this))
                .into(ivLogo);
    }


    /**
     * 设置推流相关参数
     *
     * @param streamStr
     */
    private void setStream(String streamStr) {
        //设置显示模式
        afl.setShowMode(AspectFrameLayout.SHOW_MODE.FULL);
        mProfile = new StreamingProfile();
        try {
            mProfile.setPublishUrl(streamStr);   //设置推流地址
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        mProfile.setVideoQuality(StreamingProfile.VIDEO_QUALITY_HIGH1)    //设置视屏质量
                .setAudioQuality(StreamingProfile.AUDIO_QUALITY_MEDIUM2)   //设置音频质量
                .setEncodingSizeLevel(StreamingProfile.VIDEO_ENCODING_HEIGHT_480) //设置编码等级
                .setEncoderRCMode(StreamingProfile.EncoderRCModes.QUALITY_PRIORITY)  //设置编码模式
                .setDnsManager(getMyDnsManager());
        CameraStreamingSetting setting = new CameraStreamingSetting();      //所有摄像头相关的配置
        setting.setCameraId(Camera.CameraInfo.CAMERA_FACING_BACK)
                .setContinuousFocusModeEnabled(true)
                .setCameraPrvSizeLevel(CameraStreamingSetting.PREVIEW_SIZE_LEVEL.LARGE)
                .setCameraPrvSizeRatio(CameraStreamingSetting.PREVIEW_SIZE_RATIO.RATIO_16_9);

        WatermarkSetting watermarkSetting=new WatermarkSetting(this);
        watermarkSetting.setResourceId(R.mipmap.watermark)
                .setSize(WatermarkSetting.WATERMARK_SIZE.SMALL)
                .setLocation(WatermarkSetting.WATERMARK_LOCATION.NORTH_EAST)
                .setAlpha(255
                )
              .setCustomPosition(0.8f,0.11f);

        MicrophoneStreamingSetting microphoneStreamingSetting = new MicrophoneStreamingSetting();
        microphoneStreamingSetting.setBluetoothSCOEnabled(false);
        mMediaStreamingManager = new MediaStreamingManager(this, afl, cameraPreviewSurfaceView, AVCodecType.SW_VIDEO_WITH_SW_AUDIO_CODEC);
        //加载设置的信息
//        mMediaStreamingManager.prepare(setting, mProfile);
        mMediaStreamingManager.prepare(setting,microphoneStreamingSetting,watermarkSetting, mProfile);


        mMediaStreamingManager.setStreamingStateListener(this);
        mMediaStreamingManager.setFocusAreaIndicator(mRotateLayout,
                mRotateLayout.findViewById(R.id.focus_indicator));
        mMediaStreamingManager.setNativeLoggingEnabled(false);
        cameraPreviewSurfaceView.setListener(this);
    }


    @Override
    protected void onResume() {
        super.onResume();
        mMediaStreamingManager.resume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        // You must invoke pause here.
        mMediaStreamingManager.pause();
    }

    @Override
    public void onStateChanged(final StreamingState streamingState, Object o) {
        switch (streamingState) {
            case PREPARING:
                break;
            case READY:
                //准备工作完毕,开始推流
                mMaxZoom = mMediaStreamingManager.getMaxZoom();
                countDownView.startCountDown(3, new CountDownView.countDownListener() {
                    @Override
                    public void showCountDown() {
                        startStreaming();
                    }
                });
                break;
            case CONNECTING:
                break;
            case STREAMING:
                // The av packet had been sent.
                break;
            case SHUTDOWN:
                // The streaming had been finished.
                break;
            case IOERROR:
                // Network connect error.
                break;
            case SENDING_BUFFER_EMPTY:
                break;
            case SENDING_BUFFER_FULL:
                break;
            case AUDIO_RECORDING_FAIL:
                // Failed to record audio.
                break;
            case OPEN_CAMERA_FAIL:
                // Failed to open camera.
                break;
            case DISCONNECTED:
                // The socket is broken while streaming
                break;
        }


    }

    @Override
    public void initView() {
        mPresenter = new StreamingPresenter(this);
        setNeedHideToolbar(true);
    }


    @Override
    public void showSuccessInform() {
        ToastUtils.showToast(this, "通知粉丝成功");
    }

    @Override
    public void showSuccessLiveNumber(LiveNumberQtyRs data) {
        tvViewerCount.setText("" + data.getCurOnlineMember());
    }

    @Override
    public void setPresenter(StreamContract.Presenter presenter) {

    }

    @Override
    public boolean isActive() {
        return isActive;
    }


    @Override
    public void showTip(String message) {

    }


    @OnClick({R.id.iv_flashlight, R.id.iv_camera, R.id.tv_end_live, R.id.share})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv_flashlight:
                //开启闪光灯
                setFlashLight();
                break;
            case R.id.iv_camera:
                //切换摄像头
                mHandler.removeCallbacks(mSwitcher);
                mHandler.postDelayed(mSwitcher, 100);
                break;
//            case R.id.tv_inform:
//                //通知粉丝
////                mPresenter.requestInform(mLiveData.getCode());
//                break;
            case R.id.tv_end_live:
                //结束直播
                stopStreaming();
                break;
            case R.id.share:
                //分享
                popShareView();
                break;
        }
    }

    @Override
    public void setMonter() {
//        通知粉丝防止重复点击
        RxView.clickEvents(tvInform)
                .throttleFirst(5, TimeUnit.SECONDS)
                .subscribe(new Action1<ViewClickEvent>() {
                    @Override
                    public void call(ViewClickEvent viewClickEvent) {
                        mPresenter.requestInform(mLiveData.getCode());
                    }
                });
    }

    /**
     * 开启或者关闭闪光灯
     */
    private void setFlashLight() {
        flashlightState = !flashlightState;
        if (flashlightState)
            openFlashLight();
        else
            closeFlashLight();
    }

    private void openFlashLight() {
        mMediaStreamingManager.turnLightOn();
    }

    private void closeFlashLight() {
        mMediaStreamingManager.turnLightOff();
    }

    /**
     * 弹出分享菜单
     */
    private void popShareView() {
        BottomSheetDialog dialog = new BottomSheetDialog(this);
        View dialogView = LayoutInflater.from(this).inflate(R.layout.view_share, null);
        setShareView(dialogView);
        dialog.setContentView(dialogView);
        dialog.show();
    }

    /**
     * 设置弹窗相关的监听
     *
     * @param dialogView
     */
    private void setShareView(View dialogView) {
        TextView tvWeixin = ButterKnife.findById(dialogView, R.id.tv_weixin);
        TextView tvWeixinPengyouquan = ButterKnife.findById(dialogView, R.id.tv_weixin_pengyouquan);
        tvWeixin.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                shareForWeixin(SendMessageToWX.Req.WXSceneSession);
            }
        });
        tvWeixinPengyouquan.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                shareForWeixin(SendMessageToWX.Req.WXSceneTimeline);
            }
        });
    }


    /**
     * 分享到微信
     *
     * @param WXSceneSession
     */
    private void shareForWeixin(final int WXSceneSession) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                WXWebpageObject wxWebpageObject = new WXWebpageObject();
                wxWebpageObject.webpageUrl = mLiveData.getShare().getUrl();
                WXMediaMessage wxMediaMessage = new WXMediaMessage(wxWebpageObject);
                wxMediaMessage.title = mLiveData.getShare().getTitle();
                wxMediaMessage.description = mLiveData.getShare().getContent();
                String logo = mLiveData.getShare().getLogo();
                Bitmap bitmap = Bitmap.createScaledBitmap(GetLocalOrNetBitmap(ImageUrlUtil.processUrl(40, 40, mLiveData.getShare().getLogo())), 120, 120, true);
                wxMediaMessage.thumbData = bmpToByteArray(bitmap, true);


                SendMessageToWX.Req req = new SendMessageToWX.Req();
                req.transaction = String.valueOf(System.currentTimeMillis());
                req.message = wxMediaMessage;
                req.scene = WXSceneSession;
                IWXAPI api = WXAPIFactory.createWXAPI(getApplicationContext(), WEIXIN_APP_ID, true);
                api.sendReq(req);
            }
        }).start();


//        MyApplication.getWxApi().sendReq(req);
    }

    @Override
    public boolean onSingleTapUp(MotionEvent e) {
        mMediaStreamingManager.doSingleTapUp((int) e.getX(), (int) e.getY());
        return true;
    }

    @Override
    public boolean onZoomValueChanged(float factor) {
        if (mMediaStreamingManager.isZoomSupported()) {
            mCurrentZoom = (int) (mMaxZoom * factor);
            mCurrentZoom = Math.min(mCurrentZoom, mMaxZoom);
            mCurrentZoom = Math.max(0, mCurrentZoom);
            Log.d(TAG, "zoom ongoing, scale: " + mCurrentZoom + ",factor:" + factor + ",maxZoom:" + mMaxZoom);
            if (!mHandler.hasMessages(MSG_SET_ZOOM)) {
                mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SET_ZOOM), ZOOM_MINIMUM_WAIT_MILLIS);
                return true;
            }
        }
        return false;
    }


    private class Switcher implements Runnable {
        @Override
        public void run() {
            mCurrentCamFacingIndex = (mCurrentCamFacingIndex + 1) % CameraStreamingSetting.getNumberOfCameras();

            CameraStreamingSetting.CAMERA_FACING_ID facingId;
            if (mCurrentCamFacingIndex == CameraStreamingSetting.CAMERA_FACING_ID.CAMERA_FACING_BACK.ordinal()) {
                facingId = CameraStreamingSetting.CAMERA_FACING_ID.CAMERA_FACING_BACK;
            } else if (mCurrentCamFacingIndex == CameraStreamingSetting.CAMERA_FACING_ID.CAMERA_FACING_FRONT.ordinal()) {
                facingId = CameraStreamingSetting.CAMERA_FACING_ID.CAMERA_FACING_FRONT;
            } else {
                facingId = CameraStreamingSetting.CAMERA_FACING_ID.CAMERA_FACING_3RD;
            }
            Log.i(TAG, "switchCamera:" + facingId);
            mMediaStreamingManager.switchCamera(facingId);
        }
    }


    Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_START_STREAMING:
                    //开始推流
                    new Thread(new Runnable() {
                        @Override
                        public void run() {
                            if (mMediaStreamingManager != null) {
                                mMediaStreamingManager.startStreaming();
                                new myThread().start();
                            }
                        }
                    }).start();
                    break;
                case MSG_STOP_STREAMING:
                    //结束推流
                    boolean stopStream = mMediaStreamingManager.stopStreaming();
                    L.d("" + stopStream);
                    break;
                case MSG_SET_ZOOM:
                    mMediaStreamingManager.setZoomValue(mCurrentZoom);
                    //变换焦距
                    break;
                case MSG_MUTE:
                    //静音
                    break;
                case MSG_FB:
                    //美颜
                    break;
            }
        }
    };

    protected void startStreaming() {
        mHandler.removeCallbacksAndMessages(null);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_START_STREAMING), 50);
    }

    protected void stopStreaming() {
        mHandler.removeCallbacksAndMessages(null);
        mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_STOP_STREAMING), 50);
    }


    class myThread extends Thread {
        @Override
        public void run() {
            while (isActive) {
                try {
                    Thread.sleep(10 * 1000);
                    mPresenter.requestLiveNumber(mLiveData.getCode());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private static DnsManager getMyDnsManager() {
        IResolver r0 = new DnspodFree();
        IResolver r1 = AndroidDnsServer.defaultResolver();
        IResolver r2 = null;
        try {
            r2 = new Resolver(InetAddress.getByName("119.29.29.29"));
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        return new DnsManager(NetworkInfo.normal, new IResolver[]{r0, r1, r2});
    }
}
